﻿using System;
using System.Collections.Generic;
using Sandbox.ModAPI;
using Sandbox.ModAPI.Interfaces.Terminal;

namespace Vicizlat.MultifloorCargoElevator
{
    public partial class MultifloorCargoElevator
    {
        private static bool ControlsInited = false;
        private static bool ActionsInited = false;
        private List<IMyTerminalControl> ControlsList = new List<IMyTerminalControl>();
        private List<IMyTerminalAction> ActionsList = new List<IMyTerminalAction>();
        private string AddToCustomData;
        private bool TerminalControlsChanged;
        private bool ShouldPlayDingSound;
        private bool oldShouldPlayDingSound;
        private bool RedLightWhenIntersecting;
        private bool oldRedLightWhenIntersecting;

        public void LoadTerminalControlsSettings()
        {
            if (!Elevator_block.CustomData.Contains("CabinLightRed")) CabinLightColor.R = 255;
            else CabinLightColor.R = (byte)GetNumber("CabinLightRed");
            if (!Elevator_block.CustomData.Contains("CabinLightGreen")) CabinLightColor.G = 255;
            else CabinLightColor.G = (byte)GetNumber("CabinLightGreen");
            if (!Elevator_block.CustomData.Contains("CabinLightBlue")) CabinLightColor.B = 255;
            else CabinLightColor.B = (byte)GetNumber("CabinLightBlue");
            if (!Elevator_block.CustomData.Contains("CabinLightRange")) CabinLightRange = 10;
            else CabinLightRange = GetNumberFloat("CabinLightRange");
            if (!Elevator_block.CustomData.Contains("CabinLightIntensity")) CabinLightIntensity = 5;
            else CabinLightIntensity = GetNumberFloat("CabinLightIntensity");
            ShouldPlayDingSound = !Elevator_block.CustomData.Contains("ShouldNotPlayDingSound") ? true : false;
            RedLightWhenIntersecting = !Elevator_block.CustomData.Contains("Don'tShowRedLightWhenIntersecting") ? true : false;
            if (!Elevator_block.CustomData.Contains("SoundVolume")) SoundVolume = 2;
            else SoundVolume = GetNumberFloat("SoundVolume");
        }

        private int GetNumber(string Name)
        {
            int ValuePosition = Elevator_block.CustomData.IndexOf("[", Elevator_block.CustomData.IndexOf(Name)) + 1;
            int ValueLenght = Elevator_block.CustomData.IndexOf("]", Elevator_block.CustomData.IndexOf(Name)) - ValuePosition;
            return Int32.Parse(Elevator_block.CustomData.Substring(ValuePosition, ValueLenght));
        }

        private float GetNumberFloat(string Name)
        {
            int ValuePosition = Elevator_block.CustomData.IndexOf("[", Elevator_block.CustomData.IndexOf(Name)) + 1;
            int ValueLenght = Elevator_block.CustomData.IndexOf("]", Elevator_block.CustomData.IndexOf(Name)) - ValuePosition;
            return Single.Parse(Elevator_block.CustomData.Substring(ValuePosition, ValueLenght));
        }

        public void CreateTerminalControls()
        {
            if (ControlsInited) return;
            ControlsInited = true;

            TerminalHelpers.AddSeparator(Elevator_block);
            TerminalHelpers.AddLabel(Elevator_block, "CabinLightLabel", "Platform Light Controls");
            TerminalHelpers.AddColorEditor(Elevator_block, "CabinLightColorControl", "Color", b => b.GameLogic.GetAs<MultifloorCargoElevator>().CabinLightColor, (b, v) => b.GameLogic.GetAs<MultifloorCargoElevator>().CabinLightColor = v);
            TerminalHelpers.AddSlider(Elevator_block, "CabinLightRangeSlider", "Range", b => b.GameLogic.GetAs<MultifloorCargoElevator>().CabinLightRange, (b, v) => b.GameLogic.GetAs<MultifloorCargoElevator>().CabinLightRange = v, 0, 20);
            TerminalHelpers.AddSlider(Elevator_block, "CabinLightIntensitySlider", "Intensity", b => b.GameLogic.GetAs<MultifloorCargoElevator>().CabinLightIntensity, (b, v) => b.GameLogic.GetAs<MultifloorCargoElevator>().CabinLightIntensity = v, 0, 10);
            TerminalHelpers.AddSeparator(Elevator_block);
            TerminalHelpers.AddCheckbox(Elevator_block, "ShouldPlayDingSound", "Play 'Ding' sound when stopping", b => b.GameLogic.GetAs<MultifloorCargoElevator>().ShouldPlayDingSound, (b, v) => b.GameLogic.GetAs<MultifloorCargoElevator>().ShouldPlayDingSound = v);
            TerminalHelpers.AddCheckbox(Elevator_block, "ShowRedLight", "Show Red Light When Blocked", b => b.GameLogic.GetAs<MultifloorCargoElevator>().RedLightWhenIntersecting, (b, v) => b.GameLogic.GetAs<MultifloorCargoElevator>().RedLightWhenIntersecting = v);
            TerminalHelpers.AddSlider(Elevator_block, "SoundVolumeSlider", "Sounds Volume", b => b.GameLogic.GetAs<MultifloorCargoElevator>().SoundVolume, (b, v) => b.GameLogic.GetAs<MultifloorCargoElevator>().SoundVolume = v, 0, 5);

            HideControls(Elevator_block);
        }

        public void CreateActions()
        {
            if (ActionsInited) return;
            ActionsInited = true;

            TerminalHelpers.AddAction(Elevator_block, "SendToFloor1", "Send To Floor 1", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(1), (b, v) => v.Append("F1"));
            TerminalHelpers.AddAction(Elevator_block, "SendToFloor2", "Send To Floor 2", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(2), (b, v) => v.Append("F2"));
            TerminalHelpers.AddAction(Elevator_block, "SendToFloor3", "Send To Floor 3", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(3), (b, v) => v.Append("F3"));
            TerminalHelpers.AddAction(Elevator_block, "SendToFloor4", "Send To Floor 4", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(4), (b, v) => v.Append("F4"));
            TerminalHelpers.AddAction(Elevator_block, "SendToFloor5", "Send To Floor 5", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(5), (b, v) => v.Append("F5"));
            TerminalHelpers.AddAction(Elevator_block, "SendToFloor6", "Send To Floor 6", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(6), (b, v) => v.Append("F6"));
            TerminalHelpers.AddAction(Elevator_block, "SendToFloor7", "Send To Floor 7", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(7), (b, v) => v.Append("F7"));
            TerminalHelpers.AddAction(Elevator_block, "SendToFloor8", "Send To Floor 8", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(8), (b, v) => v.Append("F8"));
            TerminalHelpers.AddAction(Elevator_block, "SendToFloor9", "Send To Floor 9", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendToFloor(9), (b, v) => v.Append("F9"));
            TerminalHelpers.AddAction(Elevator_block, "Stop", "Emergency Stop", (b) => b.GameLogic.GetAs<MultifloorCargoElevator>().SendStopSignal(), (b, v) => v.Append("STOP"));

            HideActions(Elevator_block);
        }

        private void HideControls<T>(T block) where T : IMyTerminalBlock
        {
            MyAPIGateway.TerminalControls.GetControls<T>(out ControlsList);
            foreach (var control in ControlsList)
            {
                //Logging.Instance.WriteLine("Control ID: " + control.Id + " - " + control.ToString());
                if (control.Id == "OnOff") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (control.Id == "SafetyDetach") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                //if (control.Id == "ShareInertiaTensor") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (control.Id == "Add Top Part") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (control.Id == "Reverse") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (control.Id == "UpperLimit") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (control.Id == "LowerLimit") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (control.Id == "MaxImpulseAxis") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (control.Id == "MaxImpulseNonAxis") control.Visible = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
            }
            ControlsList.Clear();
        }

        private void HideActions<T>(T block) where T : IMyTerminalBlock
        {
            MyAPIGateway.TerminalControls.GetActions<T>(out ActionsList);
            foreach (var action in ActionsList)
            {
                //Logging.Instance.WriteLine("Action ID: " + action.Id);
                if (action.Id == "OnOff") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "OnOff_On") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "OnOff_Off") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "IncreaseSafetyDetach") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "DecreaseSafetyDetach") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                //if (action.Id == "ShareInertiaTensor") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                //if (action.Id == "Add Top Part") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "Reverse") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "Extend") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "SafetyDetach") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "Retract") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "IncreaseUpperLimit") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "DecreaseUpperLimit") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "IncreaseLowerLimit") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "DecreaseLowerLimit") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "IncreaseMaxImpulseAxis") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "DecreaseMaxImpulseAxis") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "IncreaseMaxImpulseNonAxis") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
                if (action.Id == "DecreaseMaxImpulseNonAxis") action.Enabled = (b) => !b.BlockDefinition.SubtypeId.Contains("Elevator_Piston");
            }
            ActionsList.Clear();
        }

        public void CheckTerminalControlSettings()
        {
            if (!TerminalControlsChanged)
            {
                if (CabinLightColor != oldCabinLightColor)
                {
                    TerminalControlsChanged = true;
                    oldCabinLightColor = CabinLightColor;
                }
                if (CabinLightRange != oldCabinLightRange)
                {
                    TerminalControlsChanged = true;
                    CabinLightRangeChanged = true;
                    oldCabinLightRange = CabinLightRange;
                }
                if (CabinLightIntensity != oldCabinLightIntensity)
                {
                    TerminalControlsChanged = true;
                    CabinLightIntensityChanged = true;
                    oldCabinLightIntensity = CabinLightIntensity;
                }
                if (ShouldPlayDingSound != oldShouldPlayDingSound)
                {
                    TerminalControlsChanged = true;
                    oldShouldPlayDingSound = ShouldPlayDingSound;
                }
                if (RedLightWhenIntersecting != oldRedLightWhenIntersecting)
                {
                    TerminalControlsChanged = true;
                    oldRedLightWhenIntersecting = RedLightWhenIntersecting;
                }
                if (SoundVolume != oldSoundVolume)
                {
                    TerminalControlsChanged = true;
                    oldSoundVolume = SoundVolume;
                }
            }
        }

        public void SaveTerminalControlSettings()
        {
            if (TerminalControlsChanged)
            {
                AddToCustomData = "ElevatorID: {" + Elevator_block.EntityId + "}\n";
                AddToCustomData += "CabinLightRed[" + CabinLightColor.R + "]\n";
                AddToCustomData += "CabinLightGreen[" + CabinLightColor.G + "]\n";
                AddToCustomData += "CabinLightBlue[" + CabinLightColor.B + "]\n";
                AddToCustomData += "CabinLightRange[" + CabinLightRange + "]\n";
                AddToCustomData += "CabinLightIntensity[" + CabinLightIntensity + "]\n";
                if (!ShouldPlayDingSound) AddToCustomData += "ShouldNotPlayDingSound\n";
                if (!RedLightWhenIntersecting) AddToCustomData += "Don'tShowRedLightWhenIntersecting\n";
                AddToCustomData += "SoundVolume[" + SoundVolume + "]\n";
                Elevator_block.CustomData = AddToCustomData;
                TerminalControlsChanged = false;
            }
        }
    }
}